<script setup lang="tsx">
import { computed, ref, onMounted, watch } from 'vue';
import { NButton, NDivider, NPopconfirm, NTag, NProgress, NCard, NSpace, NDescriptions, NDescriptionsItem, NSpin, NAlert, NGrid, NGi, NStatistic, NInput, NSelect } from 'naive-ui';
import { useBoolean, useLoading } from '@sa/hooks';
import { jsonClone } from '@sa/utils';
import {
  fetchDeleteOutboundTask,
  fetchGetOutboundTaskList,
  fetchExportOutboundTask,
  fetchSyncTasks
} from '@/service/api/outbound';
import { useAppStore } from '@/store/modules/app';
import { useTable, useTableOperate } from '@/hooks/common/table';
import { useAuth } from '@/hooks/business/auth';
import { useDownload } from '@/hooks/business/download';
import ButtonIcon from '@/components/custom/button-icon.vue';
import { $t } from '@/locales';
import TaskOperateDrawer from './modules/task-operate-drawer.vue';
import TaskSearch from './modules/task-search.vue';
import TableHeaderOperation from '@/components/advanced/table-header-operation.vue';
import DataTable from '@/components/common/data-table.vue';
import SyncStatusMonitor from '../components/sync-status-monitor.vue';
import ScheduleManager from '../components/schedule-manager.vue';

defineOptions({
  name: 'OutboundTaskList'
});

const { hasAuth } = useAuth();
const appStore = useAppStore();
const { download } = useDownload();
const { loading: exportLoading, startLoading: startExportLoading, endLoading: endExportLoading } = useLoading();
const { loading: syncLoading, startLoading: startSyncLoading, endLoading: endSyncLoading } = useLoading();

const wrapperRef = ref<HTMLElement>();

// 统计数据
const statistics = ref({
  totalTasks: 0,
  runningTasks: 0,
  completedTasks: 0,
  pausedTasks: 0,
  totalCalls: 0,
  successRate: 0
});

const {
  columns,
  columnChecks,
  data,
  getData,
  getDataByPage,
  loading,
  mobilePagination,
  searchParams,
  resetSearchParams
} = useTable({
  apiFn: fetchGetOutboundTaskList,
  apiParams: {
    pageNum: 1,
    pageSize: 10,
    taskName: null,
    scriptName: null,
    volcanoTaskId: null,
    status: null,
    params: {}
  },
  immediate: false,
  columns: () => [
    {
      type: 'selection',
      align: 'center',
      width: 48
    },
    {
      key: 'index',
      title: $t('common.index'),
      align: 'center',
      width: 64
    },
    {
      key: 'taskName',
      title: '任务名称',
      align: 'center',
      minWidth: 150,
      ellipsis: true
    },
    {
      key: 'scriptName',
      title: '剧本名称',
      align: 'center',
      minWidth: 120,
      ellipsis: true
    },
    {
      key: 'status',
      title: '任务状态',
      align: 'center',
      width: 120,
      render: row => {
        const statusMap: Record<number, { label: string; type: 'default' | 'info' | 'success' | 'warning' | 'error' }> = {
          0: { label: '未开始', type: 'default' },
          1: { label: '进行中', type: 'info' },
          2: { label: '已结束', type: 'success' },
          3: { label: '已暂停', type: 'warning' },
          4: { label: '工作时间暂停', type: 'warning' },
          5: { label: '禁呼状态', type: 'warning' },
          6: { label: '拨打完成', type: 'success' },
          7: { label: '已终止', type: 'error' }
        };
        const status = statusMap[row.status] || { label: '未知', type: 'default' };
        return <NTag type={status.type}>{status.label}</NTag>;
      }
    },
    {
      key: 'concurrency',
      title: '并发量',
      align: 'center',
      width: 80
    },
    {
      key: 'listSize',
      title: '名单总数',
      align: 'center',
      width: 100
    },
    {
      key: 'calledSize',
      title: '已呼叫数',
      align: 'center',
      width: 100
    },
    {
      key: 'throughSize',
      title: '接通数',
      align: 'center',
      width: 100
    },
    {
      key: 'throughRate',
      title: '接通率',
      align: 'center',
      width: 120,
      render: row => {
        if (row.throughRate !== null && row.throughRate !== undefined) {
          const rate = (row.throughRate * 100).toFixed(1);
          return (
            <div class="flex-center flex-col gap-4px">
              <span class="text-14px font-medium">{rate}%</span>
              <NProgress
                type="line"
                percentage={row.throughRate * 100}
                showIndicator={false}
                height={4}
                color={row.throughRate > 0.5 ? '#18a058' : row.throughRate > 0.2 ? '#f0a020' : '#d03050'}
              />
            </div>
          );
        }
        return '-';
      }
    },
    {
      key: 'finishRate',
      title: '完成率',
      align: 'center',
      width: 120,
      render: row => {
        if (row.finishRate !== null && row.finishRate !== undefined) {
          const rate = (row.finishRate * 100).toFixed(1);
          return (
            <div class="flex-center flex-col gap-4px">
              <span class="text-14px font-medium">{rate}%</span>
              <NProgress
                type="line"
                percentage={row.finishRate * 100}
                showIndicator={false}
                height={4}
                color={row.finishRate > 0.8 ? '#18a058' : row.finishRate > 0.5 ? '#f0a020' : '#d03050'}
              />
            </div>
          );
        }
        return '-';
      }
    },
    {
      key: 'createTime',
      title: '创建时间',
      align: 'center',
      width: 180,
      render: row => {
        if (row.createTime) {
          return new Date(row.createTime).toLocaleString();
        }
        return '-';
      }
    },
    {
      key: 'operate',
      title: $t('common.operate'),
      align: 'center',
      width: 280,
      render: row => {
        return (
          <div class="flex-center gap-8px">
            {hasAuth('outbound:task:edit') && (
              <NButton type="primary" ghost size="small" onClick={() => edit(row.taskId)}>
                编辑
              </NButton>
            )}
            {hasAuth('outbound:task:pause') && row.status === 1 && (
              <NButton type="warning" ghost size="small" onClick={() => handlePauseTask(row.taskId)}>
                暂停
              </NButton>
            )}
            {hasAuth('outbound:task:resume') && row.status === 3 && (
              <NButton type="success" ghost size="small" onClick={() => handleResumeTask(row.taskId)}>
                恢复
              </NButton>
            )}
            {hasAuth('outbound:task:stop') && [1, 3].includes(row.status) && (
              <NPopconfirm onPositiveClick={() => handleStopTask(row.taskId)}>
                {{
                  default: () => '确认终止此任务？终止后无法恢复！',
                  trigger: () => (
                    <NButton type="error" ghost size="small">
                      终止
                    </NButton>
                  )
                }}
              </NPopconfirm>
            )}
            {hasAuth('outbound:task:sync') && (
              <NButton type="default" ghost size="small" onClick={() => handleSyncTask(row.taskId)}>
                同步
              </NButton>
            )}
          </div>
        );
      }
    }
  ]
});

const {
  drawerVisible,
  operateType,
  editingData,
  handleAdd,
  handleEdit,
  checkedRowKeys,
  onBatchDeleted,
  onDeleted
} = useTableOperate(data, getData);

// 计算统计数据
function calculateStatistics() {
  if (!data.value || data.value.length === 0) {
    statistics.value = {
      totalTasks: 0,
      runningTasks: 0,
      completedTasks: 0,
      pausedTasks: 0,
      totalCalls: 0,
      successRate: 0
    };
    return;
  }

  const total = data.value.length;
  const running = data.value.filter(item => item.status === 1).length;
  const completed = data.value.filter(item => [2, 6].includes(item.status)).length;
  const paused = data.value.filter(item => [3, 4, 5].includes(item.status)).length;
  const totalCalls = data.value.reduce((sum, item) => sum + (item.calledSize || 0), 0);
  const totalThrough = data.value.reduce((sum, item) => sum + (item.throughSize || 0), 0);
  const successRate = totalCalls > 0 ? (totalThrough / totalCalls) * 100 : 0;

  statistics.value = {
    totalTasks: total,
    runningTasks: running,
    completedTasks: completed,
    pausedTasks: paused,
    totalCalls,
    successRate: Math.round(successRate * 10) / 10
  };
}

async function handleBatchDelete() {
  // request
  await fetchDeleteOutboundTask(checkedRowKeys.value);

  onBatchDeleted();
}

async function handleDelete(id: CommonType.IdType) {
  // request
  await fetchDeleteOutboundTask([id]);

  onDeleted(id);
}

function edit(id: CommonType.IdType) {
  handleEdit(id);
}

async function handlePauseTask(taskId: CommonType.IdType) {
  await fetchPauseOutboundTask(taskId);
  window.$message?.success('任务已暂停');
  getData();
}

async function handleResumeTask(taskId: CommonType.IdType) {
  await fetchResumeOutboundTask(taskId);
  window.$message?.success('任务已恢复');
  getData();
}

async function handleStopTask(taskId: CommonType.IdType) {
  await fetchStopOutboundTask(taskId);
  window.$message?.success('任务已终止');
  getData();
}

async function handleSyncTask(taskId: CommonType.IdType) {
  try {
    await fetchSyncOutboundTaskStatus(taskId);
    await fetchSyncOutboundTaskDetail(taskId);
    window.$message?.success('同步完成');
    getData();
  } catch (error) {
    console.error('同步失败:', error);
  }
}

async function handleExport() {
  startExportLoading();
  try {
    await download(() => fetchExportOutboundTask(searchParams), '外呼任务列表.xlsx');
  } finally {
    endExportLoading();
  }
}

async function handleSyncData() {
  startSyncLoading();
  try {
    await fetchSyncTasks();
    window.$message.success('数据同步成功');
    getData(); // 刷新数据
  } catch (error) {
    window.$message.error('数据同步失败');
    console.error('同步失败:', error);
  } finally {
    endSyncLoading();
  }
}

// 监听数据变化，重新计算统计
onMounted(() => {
  getData();
});

// 数据加载完成后计算统计
watch(data, () => {
  calculateStatistics();
}, { immediate: true });
</script>

<template>
  <div class="min-h-500px flex-col-stretch gap-16px overflow-hidden lt-sm:overflow-auto">
    <!-- 同步状态监控 -->
    <SyncStatusMonitor />

    <!-- 定时任务管理 -->
    <ScheduleManager />

    <TaskSearch v-model:model="searchParams" @reset="resetSearchParams" @search="getDataByPage" />

    <NCard title="外呼任务管理" :bordered="false" size="small" class="card-wrapper sm:flex-1-hidden">
      <template #header-extra>
        <div class="flex items-center gap-2">
          <NButton
            type="primary"
            ghost
            :loading="syncLoading"
            @click="handleSyncData"
          >
            <template #icon>
              <icon-ic-round-sync class="text-icon" />
            </template>
            同步数据
          </NButton>
          <TableHeaderOperation
            v-model:columns="columnChecks"
            :disabled-delete="checkedRowKeys.length === 0"
            :loading="loading"
            :show-add="hasAuth('outbound:task:add')"
            :show-delete="hasAuth('outbound:task:remove')"
            :show-export="hasAuth('outbound:task:export')"
            @add="handleAdd"
            @delete="handleBatchDelete"
            @export="handleExport"
            @refresh="getData"
          />
        </div>
      </template>

      <DataTable
        v-model:checked-row-keys="checkedRowKeys"
        :columns="columns"
        :data="data"
        size="small"
        :flex-height="!appStore.isMobile"
        :scroll-x="1200"
        :loading="loading"
        remote
        :row-key="row => row.taskId"
        :pagination="mobilePagination"
        class="sm:h-full"
      />

      <TaskOperateDrawer
        v-model:visible="drawerVisible"
        :operate-type="operateType"
        :row-data="editingData"
        @submitted="getDataByPage"
      />
    </NCard>
  </div>
</template>

<style scoped>
.card-wrapper {
  box-shadow: 0 1px 2px rgba(0, 0, 0, 0.1);
  border-radius: 8px;
  transition: all 0.3s ease;
}

.card-wrapper:hover {
  box-shadow: 0 4px 12px rgba(0, 0, 0, 0.1);
}

.stat-card {
  text-align: center;
  min-height: 120px;
  display: flex;
  align-items: center;
  justify-content: center;
}

@media (max-width: 768px) {
  .stat-card {
    min-height: 100px;
  }
}

@media (max-width: 480px) {
  .stat-card {
    min-height: 80px;
  }
}
</style>
